<template>
  <div id="vue-tinymce" :style="styles">
    <!-- <input type="file" @change="handleFileUpload"> -->
    <Editor
      ref="editor"
      :key="tinymceFlag"
      v-model="editorVlaue"
      :init="setting"
      :disabled="readOnly"
    />
  </div>
</template>

<script>
import tinymce from "tinymce";
import Editor from "@tinymce/tinymce-vue";
import "tinymce/plugins/code";

import "tinymce/icons/default/icons";
import "tinymce/plugins/image";
import "tinymce/plugins/media";
import "tinymce/plugins/table";
import "tinymce/plugins/lists";
import "tinymce/plugins/contextmenu";
import "tinymce/plugins/wordcount";
import "tinymce/plugins/colorpicker";
import "tinymce/plugins/textcolor";
import "tinymce/themes/silver";
import "@npkg/tinymce-plugins/upfile";
import "@npkg/tinymce-plugins/attachment";
import axios from "axios";
import pdfjsLib from "pdfjs-dist";
export default {
  name: "vueTinymceEditor",
  components: { Editor },
  data() {
    var xhrOnProgress = function (fun) {
      xhrOnProgress.onprogress = fun;
      return function () {
        var xhr = $.ajaxSettings.xhr();
        if (typeof xhrOnProgress.onprogress !== "function") return xhr;
        if (xhrOnProgress.onprogress && xhr.upload) {
          xhr.upload.onprogress = xhrOnProgress.onprogress;
        }
        return xhr;
      };
    };
    return {
      pdfFile: null,
      pdfUrl: null,
      tinymceFlag: 1,
      baseUploadUrl: process.env.VUE_APP_BASE_API + "/api/common/upload", // 上传的图片服务器地址
      editorVlaue: this.content != null ? this.content : "",
      setting: {
        content: "", // 因为pdf文件是动态加载的，先将content设置为''
        menubar: this.readOnly ? false : true, // 菜单栏
        //inline: true,   //开启内联模式
        toolbar: this.readOnly
          ? ""
          : "undo redo | fullscreen | formatselect alignleft aligncenter alignright alignjustify | link unlink | numlist bullist | image media table emoticons | fontselect fontsizeselect forecolor backcolor | bold italic underline strikethrough | indent outdent | superscript subscript | removeformat|code",
          // : "undo redo | fullscreen | formatselect alignleft aligncenter alignright alignjustify | link unlink | numlist bullist | image media table emoticons | fontselect fontsizeselect forecolor backcolor | bold italic underline strikethrough | indent outdent | superscript subscript | removeformat|code|upfile attachment",
        plugins:
          "image code media table lists contextmenu wordcount colorpicker textcolor",
          // "image code media table lists contextmenu wordcount colorpicker textcolor upfile attachment",
        language_url: "/tinymce/langs/zh-Hans.js",
        language: "zh-Hans",
        skin_url: "/tinymce/skins/ui/oxide",
        height: this.height | this.minHeight,
        // 图片上传地址(自动上传)
        images_upload_url: this.baseUploadUrl,
        // 允许粘贴图片上传,及格式
        paste_data_images: true,
        images_file_types: "jpeg,jpg,png,gif,bmp,webp",
        attachment_max_size: 209715200,
        attachment_style:
          ".attachment>img{display:inline-block!important;max-width:30px!important;}",
        attachment_icons_path:
          "https://unpkg.com/@npkg/tinymce-plugins/plugins/attachment/icons",
        attachment_upload_handler: function (file, succFun, failFun, progressCallback) {
          var data = new FormData();
          data.append("file", file);
          axios({
            method: "POST",
            url: process.env.VUE_APP_BASE_API + "/api/common/upload",
            data: data,
            onUploadProgress: function (e) {
              if (e.lengthComputable) {
                const percent = ((e.loaded / e.total) | 0) + "%"; //计算百分比
                progressCallback(percent);
                console.log("上传进度", e.loaded / e.total); //已上传的比例
              }
            },
          })
            .then((res) => {
              if (res.data.code === 200) {
                var url = res.data.url;
                var name = res.data.originalFilename;

                succFun(url, { text: name }); //成功回调函数 text 显示的文本
              } else {
                this.$message.error("上传失败");
              }
            })
            .catch((res) => {
              this.$message.error({
                title: "文件上传失败！",
                message: "您上传的文件超过了100MB,请压缩后再上传。",
              });
            });
        },
        file_callback: function (file, succFun) {
          // 自定义处理文件操作部分

          var formData = new FormData();
          formData.append("file", file);
          axios({
            method: "POST",
            url: process.env.VUE_APP_BASE_API + "/api/common/upload",
            data: formData,
          })
            .then((res) => {
              if (res.data.code === 200) {
                var url = res.data.url;
                var name = res.data.originalFilename;

                succFun(url, { text: name }); //成功回调函数 text 显示的文本
              } else {
                this.$message.error("上传失败");
              }
            })
            .catch((res) => {
              this.$message.error({
                title: "文件上传失败！",
                message: "您上传的文件超过了100MB,请压缩后再上传。",
              });
            });
        },

        // 此处为图片上传处理函数 (手动上传)
        images_upload_handler: (blobInfo, success, failure, progress) => {
          console.log("上传处理器：");
          // 方法1：用base64的图片形式上传图片
          // const img = 'data:image/jpeg;base64,' + blobInfo.base64()
          // success(img)

          // 方法2：上传oos
          const xhr = new XMLHttpRequest();
          xhr.withCredentials = false;
          xhr.open("POST", this.baseUploadUrl);
          // xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded;charset=utf-8')
          // xhr.setRequestHeader('x-token', this.$store.getters.token)
          xhr.upload.onprogress = function (e) {
            progress((e.loaded / e.total) * 100);
          };
          // 成功结果
          xhr.onload = function () {
            if (xhr.status != 200) {
              failure("HTTP Error: " + xhr.status, { remove: true });
              return;
            }
            const json = JSON.parse(xhr.responseText);
            success(json.url);
          };
          // 失败结果
          xhr.onerror = function () {
            failure(
              "Image upload failed due to a XHR Transport error. Code: " + xhr.status
            );
          };
          // 请求数据
          const formData = new FormData();
          formData.append("file", blobInfo.blob(), blobInfo.filename());
          xhr.send(formData);
        },
      },
    };
  },
  props: {
    // 接收值父组件传递值
    value: {
      type: String,
      default: "",
    },
    /* 高度 */
    height: {
      type: Number,
      default: null,
    },
    /* 最小高度 */
    minHeight: {
      type: Number,
      default: null,
    },
    /* 只读 */
    readOnly: {
      type: Boolean,
      default: false,
    },
  },
  activated() {
    this.tinymceFlag++;
  },
  mounted() {
    this.$refs.editor.$on("init", () => {
      if (this.pdfUrl) {
        this.loadPdfFile();
      }
    });
  },
  methods: {
    // 处理上传文件
    handleFileUpload(event) {
      this.pdfFile = event.target.files[0];

      // FileReader API 将文件读取为数据URL
      const reader = new FileReader();
      reader.onloadend = () => {
        this.pdfUrl = reader.result;
        this.loadPdfFile();
      };
      reader.readAsDataURL(this.pdfFile);
    },

    // 使用pdf.js库加载和显示PDF文件
    loadPdfFile() {
      var that = this
      // 调用pdf.js库并获取PDF文件
      pdfjsLib.getDocument({ url: this.pdfUrl }).promise.then((pdf) => {
        const numPages = pdf.numPages;
        const pdfProcessingPromises = [];

        // 循环每一页，并渲染成图片
        for (let i = 1; i <= numPages; i++) {
          const processingPromise = pdf.getPage(i).then((page) => {
            const scale = 1.5;
            const viewport = page.getViewport({ scale });
            const canvas = document.createElement("canvas");
            const context = canvas.getContext("2d");
            canvas.height = viewport.height;
            canvas.width = viewport.width;

            const renderContext = {
              canvasContext: context,
              viewport,
            };

            const renderTask = page.render(renderContext);

            // 将canvas的图像数据转换为data URL
            return new Promise((resolve) => {
              renderTask.promise.then(() => {
                const imgData = canvas.toDataURL("image/png");
                resolve(imgData);
              });
            });
          });

          pdfProcessingPromises.push(processingPromise);
        }
        
        // 等待所有promise完成，然后将所有图像数据合并成一个content并加载到Tinymce中
        Promise.all(pdfProcessingPromises).then((imageDatas) => {
          const content = imageDatas
            .map((imgData) => {
              return `<img src="${imgData}"/>`;
            })
            .join("");
            console.log(content)
            console.log(imageDatas)
          that.$refs.editor.setContent(content);
        });
      });
    },
  },
  computed: {
    styles() {
      const style = {};
      if (this.minHeight) {
        style.minHeight = `${this.minHeight}px`;
      }
      if (this.height) {
        style.height = `${this.height}px`;
      }
      return style;
    },
  },
  watch: {
    value: {
      handler(val) {
        if (val !== this.editorVlaue) {
          this.editorVlaue = val === null ? "" : val;
          // if (this.Quill) {
          //   this.Quill.pasteHTML(this.currentValue);
          // }
        }
      },
      immediate: true,
    },

    editorVlaue: function (newNum, oldNum) {
      // 修改调用者传入的值
      this.$emit("update:value", newNum);
    },
  },
};
</script>

<style>
/* 富文本按钮功能优先级,最好 > 2500  弹出默认2000+ */
.tox-tinymce-aux {
  z-index: 9999 !important;
}
</style>
